import os
import re

from io import BytesIO, StringIO

import xlrd
import xlsxwriter
from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.
from rest_framework import status
from rest_framework.exceptions import ErrorDetail
from rest_framework.generics import ListAPIView
from rest_framework.pagination import PageNumberPagination
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
from xlwt import Workbook

from products.models import Products
from products.serializers import ProductsSetSerializer, ASINSerializer, ListProductSerializer
from store.models import StoreManagement
from users.models import User



class LargeResultsSetPagination(PageNumberPagination):
    page_size = 100
    page_size_query_param = 'page_size'
    max_page_size = 100

class ListProductView(ListAPIView):
    queryset = Products.objects.filter(parent=None)
    serializer_class = ListProductSerializer
    pagination_class = LargeResultsSetPagination




class ProductViewSet(ModelViewSet):
    queryset = Products.objects.all()
    serializer_class = ProductsSetSerializer

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', True)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        if getattr(instance, '_prefetched_objects_cache', None):
            # If 'prefetch_related' has been applied to a queryset, we need to
            # forcibly invalidate the prefetch cache on the instance.
            instance._prefetched_objects_cache = {}

        return Response(serializer.data)




class ProductXLSDInput(APIView):
    permission_classes = [IsAuthenticated]
    def get(self,request):
        print('┗4')
        return Response({"success_msg": "ok"}, status=status.HTTP_203_NON_AUTHORITATIVE_INFORMATION)

    def text2dict(self, v, username, prod_id=None, i=0):
        # print(i)
        wait_data = {
            "brand": v[i][1],
            "product_name": v[i][2],
            "myasin": v[i][3],
            "category": v[i][4],
            "price": v[i][5],
            "buy_box_price": None if not isinstance(v[i][6], float) else v[i][6],
            "offer_min_price": None if not isinstance(v[i][6], float) else v[i][6],
            "offer": v[i][8],
            "comments": v[i][9],
            "goods_version": v[i][10],
            "status": 2 if v[i][11] == "" else 1,
            "color": '-' if v[i][12] == '' else v[i][12],
            "size": '-' if v[i][13] == '' else v[i][13],
            "country": '-' if v[i][14] == '' else v[i][14],
            "star": '-' if v[i][15] == '' else v[i][15],
            "seller_type": '-' if v[i][16] == '' else v[i][16],
            "haven_cart": 1 if v[i][17] == 'Y' else 0,
            "product_url": v[i][18],
            "small_image_url": v[i][19],
            "heavy_image_url": v[i][20],
            "local_image_url": v[i][21],
            "remark": v[i][22],
            "goods_short_desc": '-' if v[i][23] == '' else v[i][23],
            "goods_long_desc": '-' if v[i][24] == '' else v[i][24],
            "task": v[i][25],
            "get_time": v[i][26],
            "best_seller_rank": v[i][27],
            "can_sell_info": '-' if v[i][28] == '' else v[i][28],
            "general_info": '-' if v[i][29] == '' else v[i][29],  # 主体为空  变体有描述
            "parent": prod_id,
            "user": username,
        }
        return wait_data

    def post(self, request):
        # json_data = request.POST.get('user_id')
        # if not json_data:
        #     return Response({'error_msg': '缺少参数user_id'},status=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE)
        # user_id = int(json_data)
        user = request.user
        username = user.username

        # store = StoreManagement.objects.get(staff=user)
        # 接收文件
        f = request.FILES['prodfile']
        # print(f)
        type_excel = f.name.split('.').pop()
        if type_excel == 'xls' or 'xlsx':
            wb = xlrd.open_workbook(filename=None, file_contents=f.read())
            table = wb.sheets()[0]
            nrows = table.nrows  # 获取行数
            ncole = table.ncols
            if ncole != 30: return Response({"error": "请按模板文件填写"}, status=status.HTTP_417_EXPECTATION_FAILED)
            prod_dict = dict()
            # 构建主体变体组合字典 为下一步入库准备
            for i in range(1,nrows):
                row_values = table.row_values(i)
                number = re.search('任务第([0-9]*)个', row_values[25])

                if prod_dict.get(number.group(1)) is None: prod_dict[number.group(1)] = list()
                prod_dict[number.group(1)].append(row_values)

            copy_asin = 0
            new_asin = 0
            # 开始分情况 循环导入
            for k, v in prod_dict.items():
                if len(v) == 1:  # 列表元素只包含主体
                    # prod_obj.create(brand=v[0][1])
                    wait_data = self.text2dict(v, username)

                    serializer = ProductsSetSerializer(data=wait_data)
                    serializer.is_valid()

                    if serializer.errors.get('myasin') == [ErrorDetail(string='具有 原始ASIN 的 产品 已存在。', code='unique')]:
                        copy_asin += 1
                    else:
                        serializer.save()
                        new_asin += 1
                elif len(v) > 1:   # 列表元素包含主体和变体

                    wait_data = self.text2dict(v, username)
                    serializer = ProductsSetSerializer(data=wait_data)
                    serializer.is_valid()
                    # print(serializer.errors)
                    # print(serializer.errors['myasin'],type(serializer.errors['myasin']))
                    if serializer.errors.get('myasin') == [ErrorDetail(string='具有 原始ASIN 的 产品 已存在。', code='unique')]:
                        copy_asin += 1
                        prod_id = Products.objects.get(myasin=v[0][3]).id
                    else:
                        serializer.save()
                        new_asin += 1
                        prod_id = Products.objects.all().order_by('-id').first().id
                    for i in range(1, len(v)):
                        wait_data = self.text2dict(v, username, prod_id, i)
                        serializer = ProductsSetSerializer(data=wait_data)
                        serializer.is_valid()
                        if serializer.errors.get('myasin') == [
                            ErrorDetail(string='具有 原始ASIN 的 产品 已存在。', code='unique')]:
                            copy_asin += 1
                        else:
                            serializer.save()
                            new_asin += 1


            # try:
            #     with transaction.atomic():
            #         for i in range(1, nrows):
            #             row_values = table.row_values(i)
            #             print("*******")
            #             user = User.objects.get(id=user_id)
            #             tort = Torts.objects.create(staff=user, tort_company_ip=row_values[0], tort_asin=row_values[1],
            #                                         old_asin=row_values[2], tort_content=row_values[3],
            #                                         deal_with_tort=row_values[4],
            #                                         tort_image_url=row_values[5], )
            # except Exception as e:
            #     return Response({"error_msg": str(e)})

        else:
            return Response({'error_msg': '文件类型不是xls或xlsx'}, status=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE)

        return Response({'success_msg': f'导入成功，新增{new_asin}条数据，有{copy_asin}条重复ASIN'}, status=status.HTTP_200_OK)



class NewASIN2MysqlView(APIView):

    # permission_classes = [IsAuthenticated]

    def post(self, request):
        # 上传ASIN新旧对照表
        user = request.user

        f = request.FILES.get("asin_file")
        if not f: return Response({"error_msg":"请选择文件"},status=status.HTTP_417_EXPECTATION_FAILED)
        type_excel = f.name.split('.').pop()
        if type_excel == 'xls' or 'xlsx':
            wb = xlrd.open_workbook(filename=None, file_contents=f.read())
            table = wb.sheets()[0]
            nrows = table.nrows  # 获取行数
            ncole = table.ncols  # 获取列数
            if ncole != 3: return Response({"error": "请按模板文件填写"}, status=status.HTTP_417_EXPECTATION_FAILED)
            resp_list = list()
            success_num = 0
            for i in range(1, nrows):
                prod_dict = dict()
                row_values = table.row_values(i)
                # print(row_values)
                prod_dict['old_asin'] = row_values[0]
                # try:
                #     Products.objects.get(myasin=row_values[0])
                # except Exception as e:
                #     print(e)
                prod_dict['new_asin'] = row_values[1]
                prod_dict['user'] = user.username
                prod_dict['store'] = row_values[2]
                serializer = ASINSerializer(data=prod_dict)
                serializer.is_valid()
                if serializer.errors.get('old_asin') == [ErrorDetail(string='属性 myasin 为 07WH1YJ65 的对象不存在。', code='does_not_exist')]:

                    print(re.search(r'为 (\w*) 的对象不存在',serializer.errors.get('old_asin')[0]).group(1))
                    err_str = f'第{i}条数据原ASIN未录入产品库'
                    resp_list.append(err_str)
                    continue
                serializer.save()
                success_num += 1

        return Response({"success_msg": f"上传成功{success_num}条数据，{resp_list}"}, status=status.HTTP_201_CREATED)

    def get(self, request):

        # 下载模板ASIN新旧对照表
        list_obj = [
            {"old_asin": "B07WH1YJ65", 'new_asin': 'X07X2GAJ3R', "store": "zhaol1988l@sina.com"},
            {'old_asin': "B07V9SZ42N", "new_asin": "CAWE123WRF", "store": "zhaol1988l@sina.com"},
            {'old_asin': "B07V9HJY8J", "new_asin": "AXVER2DSVA", "store": "zhaol1988l@sina.com"},
            {'old_asin': "B07V9HJMMM", "new_asin": "CBNFDG345S", "store": "zhaol1988l@sina.com"},
            {'old_asin': "B07V9H7CQG", "new_asin": "ASFARH5672", "store": "zhaol1988l@sina.com"},
            {'old_asin': "B07V9GZ9KR", "new_asin": "ADGDG46FHG", "store": "zhaol1988l@sina.com"},
        ]

        if list_obj:
            # 创建工作薄
            ws = Workbook(encoding='utf-8')
            w = ws.add_sheet(u"数据报表第一页")
            w.write(0, 0, u"原ASIN")
            w.write(0, 1, u"新ASIN")
            w.write(0, 2, u"店铺")


            # 写入数据
            excel_row = 1
            for obj in list_obj:
                old_asin = obj['old_asin']
                new_asin = obj['new_asin']
                store = obj['store']
                w.write(excel_row, 0, old_asin)
                w.write(excel_row, 1, new_asin)
                w.write(excel_row, 2, store)
                excel_row += 1
            # 检测文件是够存在
            # 方框中代码是保存本地文件使用，如不需要请删除该代码
            ###########################
            # exist_file = os.path.exists("test.xls")
            # if exist_file:
            #     os.remove(r"test.xls")
            # ws.save("test.xls")
            ############################
            x_io = BytesIO()
            ws.save(x_io)
            x_io.seek(0)
            response = HttpResponse(x_io.getvalue(), content_type='application/vnd.ms-excel')
            response['Content-Disposition'] = 'attachment; filename=ASIN新旧模板.xlsx'
            response.write(x_io.getvalue())
            return response


class TTTTTTest(APIView):
    def post(self,request):
        f = request.FILES.get("tort_file")

        type_excel = f.name.split('.').pop()
        if type_excel == 'xls' or 'xlsx':
            wb = xlrd.open_workbook(filename=None, file_contents=f.read())
            table = wb.sheets()[0]
            nrows = table.nrows  # 获取行数
            ncole = table.ncols  # 获取列数
            for i in range(1, nrows):
                row_values = table.row_values(i)
                print(row_values)

        return Response("ok")





class DeleteAll(APIView):
    def get(self, request):
        Products.objects.all().delete()
        return Response({"success":"OK"})






